package com.dudu.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import com.dudu.access.ConvertAudio;
import com.dudu.bean.AccountBean;
import com.dudu.bean.AppExtendBean;
import com.dudu.enumeration.AbilityTypeEnum;
import com.dudu.service.IAccountExtendService;
import com.dudu.service.IAppExtendService;
import com.dudu.service.IAudeoNoticeService;
import com.dudu.service.ICheckValidityService;
import com.dudu.service.ILogService;
import com.dudu.service.IOperationPlatformService;
import com.dudu.service.impl.AccountExtendServiceImpl;
import com.dudu.service.impl.AppExtendServiceImpl;
import com.dudu.service.impl.AudeoNoticeServiceImpl;
import com.dudu.service.impl.CheckValidityServiceImpl;
import com.dudu.service.impl.LogService;
import com.dudu.service.impl.OperationPlatformServiceImpl;
import com.dudu.utils.DateUtils;
import com.dudu.utils.HttpRequest;
import com.dudu.utils.PhoneUtils;
import com.dudu.utils.VoiceUtil;

import core.CoreService;

/**
 * 语音留言开放接口v4.0
 * 
 * @author 危东
 * @date 2016-5-10
 */
public class OpenAbilityAUDEOController extends CoreService implements IOpenAbilityAUDEOController {

    private ILogService logService = new LogService();
    // app扩展信息操作
    private IAppExtendService appExtendService = new AppExtendServiceImpl();

    private IAccountExtendService accountExtendService = new AccountExtendServiceImpl();
    // 验证信息类
    private ICheckValidityService checkValidityService = new CheckValidityServiceImpl();
    // 运营平台相关操作
    private IOperationPlatformService operationPlatformService = new OperationPlatformServiceImpl();
    // 文件上传最大长度--设置为10M
    private Long fileMaxLength = (long) (10 * 1024 * 1024);
    // 被叫人数限定
    private int calleeNum = 51;
    // 语音信息能力调用
    private IAudeoNoticeService audeoNoticeService = new AudeoNoticeServiceImpl();

    /**
     * 发起语音留言 旧版
     * 
     * @return
     */
    @Override
    public String sendAudeoNotice() {
	log.info("load sendAudeoNotice");
	long begin = Calendar.getInstance().getTimeInMillis();
	// 接口请求参数
	List<String[]> checkParamlist = new ArrayList<String[]>();
	// 主叫号码
	String caller = this.getRequest().getHeader("caller");
	String[] callerStr = { "caller", caller, "20", "0", "str" };
	checkParamlist.add(callerStr);
	// 被叫号码：以‘,’分割
	String called = this.getRequest().getHeader("called");
	String[] calledStr = { "called", called, "200", "0", "str" };
	checkParamlist.add(calledStr);
	// 被叫号码，json数组[{"phone":"17001090122","msg_id":"49810560379194247739837403838602"}]
	String calledData = this.getRequest().getHeader("called_data");
	String[] called_dataStr = { "calledData", calledData, "1000", "1", "str" };
	checkParamlist.add(called_dataStr);
	boolean isCalledDataNull = true;
	if (StringUtils.isNotBlank(calledData)) {
	    isCalledDataNull = false;
	} else {
	    calledData = "";
	}
	// app_key应用标识
	String app_key = this.getRequest().getHeader("app_key");
	String[] app_keyStr = { "app_key", app_key, "50", "0", "str" };
	checkParamlist.add(app_keyStr);
	// cust_account账号标识
	String cust_account = this.getRequest().getHeader("cust_account");
	String[] cust_accountStr = { "cust_account", cust_account, "50", "0", "str" };
	checkParamlist.add(cust_accountStr);
	// 发起语音短信的用户ID
	String ext_terminalCode = this.getRequest().getHeader("ext_terminalCode");
	String[] ext_terminalCodeStr = { "ext_terminalCode", ext_terminalCode, "50", "0", "str" };
	checkParamlist.add(ext_terminalCodeStr);
	// 时间戳
	String timestamp = this.getRequest().getHeader("timestamp");
	String[] timestampStr = { "timestamp", timestamp, "20", "0", "str" };
	checkParamlist.add(timestampStr);
	// 认证码
	String sign = this.getRequest().getHeader("sign");
	String[] signStr = { "sign", sign, "50", "0", "str" };
	checkParamlist.add(signStr);
	// 发送语音短信的文字信息
	String content = this.getRequest().getHeader("content");
	String[] contentStr = { "content", content, "500", "0", "str" };
	checkParamlist.add(contentStr);
	// 预约发起短信时间
	String schedule_send_time = this.getRequest().getHeader("schedule_send_time");
	String[] schedule_send_timeStr = { "schedule_send_time", schedule_send_time, "50", "1", "date" };
	checkParamlist.add(schedule_send_timeStr);
	// 语音通信预约后，通信发起sessionid接收地址
	String push_url = this.getRequest().getHeader("push_url");
	String[] push_urlStr = { "push_url", push_url, "1000", "1", "str" };
	checkParamlist.add(push_urlStr);
	// 前导音
	String tts_content = this.getRequest().getHeader("tts_content");
	try {
	    // 判断如果前导音为空未收到参数，则处理为空字符串
	    if (StringUtils.isBlank(tts_content)) {
		tts_content = "";
	    }
	    // 对中文编码进行处理
	    tts_content = URLDecoder.decode(tts_content, "UTF-8");
	} catch (UnsupportedEncodingException e1) {
	    e1.printStackTrace();
	}
	String[] tts_contentStr = { "tts_content", tts_content, "50", "1", "str" };
	checkParamlist.add(tts_contentStr);
	// ISV自行定义使用哪个号码发起通话
	String pool_ability_id = this.getRequest().getHeader("pool_ability_id");
	String[] pool_ability_idStr = { "pool_ability_id", pool_ability_id, "20", "1", "str" };
	checkParamlist.add(pool_ability_idStr);
	// 判断如果号码参数为空未收到参数，则处理为空字符串
	if (StringUtils.isBlank(pool_ability_id)) {
	    pool_ability_id = "";
	}
	// 是否为一批次
	String batch_number = this.getRequest().getHeader("batch_number");
	String[] batch_numberStr = { "batch_number", batch_number, "100", "1", "str" };
	checkParamlist.add(batch_numberStr);
	if (StringUtils.isBlank(batch_number)) {
	    batch_number = "";
	}
	// 强制使用平台号码(值为1时，强制使用平台号码发起)
	String usePlatNbr = this.getRequest().getHeader("usePlatNbr");
	String[] usePlatNbrStr = { "usePlatNbr", usePlatNbr, "20", "1", "str" };
	checkParamlist.add(usePlatNbrStr);
	if (StringUtils.isBlank(usePlatNbr) || !"1".equals(usePlatNbr)) { // 不为1时不强制使用平台号
	    usePlatNbr = "";
	}
	// 语音通知类型：VOICE70，70字文字语音通知；VOICE140，140字文字语音通知
	String voice_type = this.getRequest().getHeader("voice_type"); // 可以为空
	String[] voice_typeStr = { "voice_type", voice_type, "10", "1", "str" };
	checkParamlist.add(voice_typeStr);
	if (StringUtils.isBlank(voice_type)) {
	    voice_type = "";
	}
	JSONObject object = null;
	try {
	    object = this.checkParams(checkParamlist);
	    if (null == object) {
		object = new JSONObject();
		JSONArray calledJsonArray = new JSONArray();
		if (!isCalledDataNull) {
		    calledJsonArray = JSONArray.fromObject(calledData);
		    called = VoiceUtil.parsePhone(calledJsonArray);
		}
		// 判断手机号码是否正确，过滤外国号码等
		if (PhoneUtils.filterIssueNumber(caller) && PhoneUtils.filterIssueNumber(called)) {
		    // 处理重复的电话号码
		    if (isCalledDataNull) {
			called = PhoneUtils.phoneNumDereplication(called);
		    }
		    // 被叫人数限定
		    String[] calleeStr = called.split(",");
		    if (calleeStr != null && calleeStr.length < calleeNum) {
			// 查询应用信息
			AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(app_key);
			// 判断app信息是否为空
			if (appExtendBean != null) {
			    // 根据cust_account查询账号信息
			    AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(cust_account);
			    // 判断账号信息是否找到
			    if (accountBean != null) {
				// 验证秘钥信息
				if (checkValidityService.toolsCheckSign(cust_account, accountBean.getKey_private(), timestamp, sign)) {
				    String abilityType = AbilityTypeEnum.VOICE.getKey();
				    abilityType = VoiceUtil.changeAbilityTypeByVoiceType(abilityType, voice_type, "audio", "运营平台");
				    // 到运营平台验证账号相关信息--判断是否可以通话--因为语音留言与文字留言属于一个产品，因此需要使用文字留言key做校验
				    if (operationPlatformService.platformAuthentication(object, appExtendBean, accountBean, abilityType)) {
					// 首先开始文件上传

					SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
					String fileName = null;
					// 拼写目录名称
					SimpleDateFormat sdfMonth = new SimpleDateFormat("yyyyMM");
					String monthStr = sdfMonth.format(new Date()) + "/";
					fileName = sdf.format(new Date()) + ((int) (Math.random() * 9000) + 1000);// 上传,调接口的名字
					// 获取项目绝对路径
					String dpath = this.getRequest().getSession().getServletContext().getRealPath("../");
					log.info("文件存储目录：" + dpath);
					// 将各个账号的录音信息存放在相应账号的目录下
					dpath = dpath + "/upload_voice/" + cust_account + "/" + monthStr;
					// 创建文件夹
					File fdir = new File(dpath);
					if (!fdir.exists()) {
					    fdir.mkdirs();
					}
					// 读取数据流
					byte[] data = null;
					try {
					    data = HttpRequest.readStream(this.getRequest().getInputStream());

					} catch (SocketTimeoutException e1) {
					    e1.printStackTrace();
					} catch (IOException e1) {
					    e1.printStackTrace();
					}
					// 查看文件大小
					Long fileLength = (long) data.length;
					// log.info("----------------------------------"+fileLength);
					// 判断上传文件大小，如果文件大于配置的文件大小，则报错
					if (fileMaxLength < fileLength) {
					    object.put("result", "-1");
					    object.put("describe", "文件大小超过10M");
					    object.put("code", "0506");
					} else {
					    // 根据系统时间生成上传后保存的文件名
					    String t_ext = content.substring(content.lastIndexOf("."));
					    // 拼写目录信息
					    String completeFileName = dpath + fileName + t_ext;
					    File localFileName = new File(completeFileName);
					    try {
						// 写入文件
						FileOutputStream fileOutputStream = new FileOutputStream(localFileName);
						fileOutputStream.write(data);
						fileOutputStream.close();
					    } catch (FileNotFoundException e1) {
						e1.printStackTrace();
						object.put("result", "-1");
						object.put("describe", "文件获取失败");
						object.put("code", "0505");
					    } catch (IOException e) {
						e.printStackTrace();
						object.put("result", "-1");
						object.put("describe", "文件获取失败");
						object.put("code", "0505");
					    }
					    // 开始处理上传文件到IMS
					    Map<String, String> paramMap = new HashMap<String, String>();
					    paramMap.put("Name", fileName);
					    // 文件类型转换
					    String f = "";
					    if (t_ext.equals(".amr")) {
						f = dpath + fileName + ".mp3";
						boolean res = ConvertAudio.convert(completeFileName, f);
						if (!res) {
						    log.info("格式转化失败");
						    object.put("result", "-1");
						    object.put("describe", "文件格式转化失败");
						    object.put("code", "0504");
						} else {
						    completeFileName = f;
						}
					    } else {
						f = completeFileName;
					    }
					    try {
						object = audeoNoticeService.sendAudeoNotice(appExtendBean, accountBean, ext_terminalCode, caller, called, content,
							schedule_send_time, paramMap, completeFileName, push_url, tts_content, pool_ability_id, batch_number, usePlatNbr,
							calledJsonArray, voice_type);
					    } catch (Exception e) {
						object = new JSONObject();
						object.put("result", "-1");
						object.put("describe", "语音通知异常");
						object.put("errorMsg", e);
						object.put("code", "0501");
					    }
					}

				    } else {
					object.put("result", "-1");
					object.put("code", object.getString("code"));
					object.put("describe", object.getString("describe"));
				    }
				} else {
				    object.put("result", "-1");
				    object.put("describe", "参数sign错误");
				    object.put("code", "0001");
				}
			    } else {
				object.put("result", "-1");
				object.put("describe", "计费账号不存在");
				object.put("code", "0002");
			    }
			} else {
			    object.put("result", "-1");
			    object.put("describe", "请使用正确的应用标识");
			    object.put("code", "0007");
			}
		    } else {
			object.put("result", "-1");
			object.put("describe", "单次提交的手机号码数量不能超过" + calleeNum + "个");
			object.put("code", "0502");
		    }
		} else {
		    object.put("result", "-1");
		    object.put("describe", "号码格式错误");
		    object.put("code", "0004");
		}
	    }
	} catch (Exception e) {
	    log.info("********发起语音留言失败**********" + e);
	    object = new JSONObject();
	    object.put("result", "-1");
	    object.put("describe", "语音通知异常");
	    object.put("errorMsg", e.getMessage());
	    object.put("code", "0501");
	}
	// 3、返回结果
	log.info("VoiceAbilityAction sendAudeoNotice returnData == " + object.toString());
	// 写日志
	double end = Calendar.getInstance().getTimeInMillis();
	double during = Double.valueOf((end - begin)) / 1000;
	// 拼写写入日志内容
	String request_msg = "ext_terminalCode:" + ext_terminalCode + "|app_key:" + app_key + "|cust_account:" + cust_account + "|caller:" + caller + "|called:"
		+ (called.length() > 200 ? called.substring(0, 200) : called) + "|calledData:" + (calledData.length() > 200 ? calledData.substring(0, 200) : calledData)
		+ "|timestamp:" + timestamp + "|sign:" + sign + "|schedule_send_time:" + schedule_send_time + "|content:" + content + "|tts_content:" + tts_content
		+ "|pool_ability_id:" + pool_ability_id + "|usePlatNbr:" + usePlatNbr + "batch_number:" + batch_number + "|voice_type:" + voice_type + "|push_url:" + push_url;
	this.logService.logInterface(during, "sendAudeoNoticeV4", request_msg.length() > 500 ? request_msg.substring(0, 500) : request_msg,
		object.toString().length() > 200 ? object.toString().substring(0, 200) : object.toString(), object.getString("result").length() > 200 ? object.getString("result")
			.substring(0, 200) : object.getString("result"), DateUtils.getCurrentTime(), this.getRequest().getRemoteAddr(), caller);
	object.remove("errorMsg");
	return returnData(object.toString());
    }

    /**
     * 发起语音留言新版
     * 
     * @return
     */
    @Override
    public String sendAudeoNoticeByMediaName() {
	log.info("load sendAudeoNoticeByMediaName");
	long begin = Calendar.getInstance().getTimeInMillis();
	// 接口请求参数
	List<String[]> checkParamlist = new ArrayList<String[]>();
	// 主叫号码
	String caller = this.getRequest().getParameter("caller");
	String[] callerStr = { "caller", caller, "20", "0", "str" };
	checkParamlist.add(callerStr);
	// 被叫号码：以‘,’分割
	String called = this.getRequest().getParameter("called");
	String[] calledStr = { "called", called, "1000", "0", "str" };
	checkParamlist.add(calledStr);
	// 被叫号码，json数组[{"phone":"17001090122","msg_id":"49810560379194247739837403838602"}]
	String calledData = this.getRequest().getParameter("called_data");
	String[] called_dataStr = { "calledData", calledData, "1000", "1", "str" };
	checkParamlist.add(called_dataStr);
	boolean isCalledDataNull = true;
	if (StringUtils.isNotBlank(calledData)) {
	    isCalledDataNull = false;
	} else {
	    calledData = "";
	}
	// app_key应用标识
	String app_key = this.getRequest().getParameter("app_key");
	String[] app_keyStr = { "app_key", app_key, "50", "0", "str" };
	checkParamlist.add(app_keyStr);
	// cust_account账号标识
	String cust_account = this.getRequest().getParameter("cust_account");
	String[] cust_accountStr = { "cust_account", cust_account, "50", "0", "str" };
	checkParamlist.add(cust_accountStr);
	// 发起语音短信的用户ID
	String ext_terminalCode = this.getRequest().getParameter("ext_terminalCode");
	String[] ext_terminalCodeStr = { "ext_terminalCode", ext_terminalCode, "50", "0", "str" };
	checkParamlist.add(ext_terminalCodeStr);
	// 时间戳
	String timestamp = this.getRequest().getParameter("timestamp");
	String[] timestampStr = { "timestamp", timestamp, "20", "0", "str" };
	checkParamlist.add(timestampStr);
	// 认证码
	String sign = this.getRequest().getParameter("sign");
	String[] signStr = { "sign", sign, "50", "0", "str" };
	checkParamlist.add(signStr);
	// 发送语音名称
	String mediaName = this.getRequest().getParameter("mediaName");
	String[] mediaNameStr = { "mediaName", mediaName, "50", "0", "str" };
	checkParamlist.add(mediaNameStr);

	// 预约发起短信时间
	String schedule_send_time = this.getRequest().getParameter("schedule_send_time");
	String[] schedule_send_timeStr = { "schedule_send_time", schedule_send_time, "50", "1", "date" };
	checkParamlist.add(schedule_send_timeStr);
	// 语音通信预约后，通信发起sessionid接收地址
	String push_url = this.getRequest().getParameter("push_url");
	String[] push_urlStr = { "push_url", push_url, "1000", "1", "str" };
	checkParamlist.add(push_urlStr);
	// 前导音
	String tts_content = this.getRequest().getParameter("tts_content");
	String[] tts_contentStr = { "tts_content", tts_content, "50", "1", "str" };
	checkParamlist.add(tts_contentStr);
	// ISV自行定义使用哪个号码发起通话
	String pool_ability_id = this.getRequest().getParameter("pool_ability_id");
	String[] pool_ability_idStr = { "pool_ability_id", pool_ability_id, "20", "1", "str" };
	checkParamlist.add(pool_ability_idStr);
	// 判断如果号码参数为空未收到参数，则处理为空字符串
	if (StringUtils.isBlank(pool_ability_id)) {
	    pool_ability_id = "";
	}
	// 是否为一批次
	String batch_number = this.getRequest().getParameter("batch_number");
	String[] batch_numberStr = { "batch_number", batch_number, "100", "1", "str" };
	checkParamlist.add(batch_numberStr);
	if (StringUtils.isBlank(batch_number)) {
	    batch_number = "";
	}
	// 强制使用平台号码(值为1时，强制使用平台号码发起)
	String usePlatNbr = this.getRequest().getParameter("usePlatNbr");
	String[] usePlatNbrStr = { "usePlatNbr", usePlatNbr, "20", "1", "str" };
	checkParamlist.add(usePlatNbrStr);
	if (StringUtils.isBlank(usePlatNbr) || !"1".equals(usePlatNbr)) { // 不为1时不强制使用平台号
	    usePlatNbr = "";
	}
	// 语音通知类型：VOICE70，70字文字语音通知；VOICE140，140字文字语音通知
	String voice_type = this.getRequest().getParameter("voice_type"); // 可以为空
	String[] voice_typeStr = { "voice_type", voice_type, "10", "1", "str" };
	checkParamlist.add(voice_typeStr);
	if (StringUtils.isBlank(voice_type)) {
	    voice_type = "";
	}
	JSONObject object = new JSONObject();
	try {
	    object = this.checkParams(checkParamlist);
	    if (null == object) {
		object = new JSONObject();
		JSONArray calledJsonArray = new JSONArray();
		if (!isCalledDataNull) {
		    calledJsonArray = JSONArray.fromObject(calledData);
		    called = VoiceUtil.parsePhone(calledJsonArray);
		}
		// 判断如果前导音为空未收到参数，则处理为空字符串
		if (StringUtils.isBlank(tts_content)) {
		    tts_content = "";
		}
		// 对中文编码进行处理
		tts_content = URLDecoder.decode(tts_content, "UTF-8");
		// 判断手机号码是否正确，过滤外国号码等
		if (PhoneUtils.filterIssueNumber(caller) && PhoneUtils.filterIssueNumber(called)) {
		    // 处理重复的电话号码
		    if (isCalledDataNull) {
			called = PhoneUtils.phoneNumDereplication(called);
		    }
		    // 被叫人数限定
		    String[] calleeStr = called.split(",");
		    if (calleeStr != null && calleeStr.length < calleeNum) {
			// 查询应用信息
			AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(app_key);
			// 判断app信息是否为空
			if (appExtendBean != null) {
			    // 根据cust_account查询账号信息
			    AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(cust_account);
			    // 判断账号信息是否找到
			    if (accountBean != null) {
				// 验证秘钥信息
				if (checkValidityService.toolsCheckSign(cust_account, accountBean.getKey_private(), timestamp, sign)) {
				    String abilityType = AbilityTypeEnum.VOICE.getKey();
				    abilityType = VoiceUtil.changeAbilityTypeByVoiceType(abilityType, voice_type, "audio", "运营平台");
				    // 到运营平台验证账号相关信息--判断是否可以通话--因为语音留言与文字留言属于一个产品，因此需要使用文字留言key做校验
				    if (operationPlatformService.platformAuthentication(object, appExtendBean, accountBean, abilityType)) {
					object = audeoNoticeService.sendAudeoNoticeV4(appExtendBean, accountBean, ext_terminalCode, caller, called, mediaName, schedule_send_time,
						push_url, tts_content, pool_ability_id, batch_number, usePlatNbr, calledJsonArray, voice_type);
				    } else {
					object.put("result", "-1");
					object.put("code", object.getString("code"));
					object.put("describe", object.getString("describe"));
				    }
				} else {
				    object.put("result", "-1");
				    object.put("describe", "参数sign错误");
				    object.put("code", "0001");
				}
			    } else {
				object.put("result", "-1");
				object.put("describe", "计费账号不存在");
				object.put("code", "0002");
			    }
			} else {
			    object.put("result", "-1");
			    object.put("describe", "请使用正确的应用标识");
			    object.put("code", "0007");
			}
		    } else {
			object.put("result", "-1");
			object.put("describe", "单次提交的手机号码数量不能超过" + calleeNum + "个");
			object.put("code", "0502");
		    }
		} else {
		    object.put("result", "-1");
		    object.put("describe", "号码格式错误");
		    object.put("code", "0004");
		}
	    }
	} catch (Exception e) {
	    log.info("********发起语音留言失败**********" + e);
	    object = new JSONObject();
	    object.put("result", "-1");
	    object.put("describe", "语音通知异常");
	    object.put("errorMsg", e.getMessage());
	    object.put("code", "0501");
	}
	// 3、返回结果
	log.info("VoiceAbilityAction sendAudeoNoticeByMediaName returnData == " + object.toString());
	// 写日志
	double end = Calendar.getInstance().getTimeInMillis();
	double during = Double.valueOf((end - begin)) / 1000;
	// 拼写写入日志内容
	String request_msg = "ext_terminalCode:" + ext_terminalCode + "|app_key:" + app_key + "|cust_account:" + cust_account + "|caller:" + caller + "|called:"
		+ (called.length() > 200 ? called.substring(0, 200) : called) + "|calledData:" + (calledData.length() > 200 ? calledData.substring(0, 200) : calledData)
		+ "|timestamp:" + timestamp + "|sign:" + sign + "|schedule_send_time:" + schedule_send_time + "|mediaName:" + mediaName + "|tts_content:" + tts_content
		+ "|pool_ability_id:" + pool_ability_id + "|usePlatNbr:" + usePlatNbr + "batch_number:" + batch_number + "|voice_type:" + voice_type + "|push_url:" + push_url;
	this.logService.logInterface(during, "sendAudeoNoticeByMediaName", request_msg.length() > 500 ? request_msg.substring(0, 500) : request_msg,
		object.toString().length() > 200 ? object.toString().substring(0, 200) : object.toString(), object.getString("result").length() > 200 ? object.getString("result")
			.substring(0, 200) : object.getString("result"), DateUtils.getCurrentTime(), this.getRequest().getRemoteAddr(), caller);
	object.remove("errorMsg");
	System.out.println(object.toString());
	return returnData(object.toString());
    }

    /**
     * 重发语音通知
     * 
     * @return
     */
    @Override
    public String sendAudeoNoticeLet() {
	log.info("load sendVoiceNoticeLet 重发语音通知");
	long begin = Calendar.getInstance().getTimeInMillis();
	// 接口请求参数
	List<String[]> checkParamlist = new ArrayList<String[]>();
	// 主叫号码
	String caller = this.getRequest().getParameter("caller");
	String[] callerStr = { "caller", caller, "20", "0", "str" };
	checkParamlist.add(callerStr);
	// 被叫号码：以‘,’分割
	String called = this.getRequest().getParameter("called");
	String[] calledStr = { "called", called, "600", "0", "str" };
	checkParamlist.add(calledStr);
	// 被叫号码，json数组[{"phone":"17001090122","msg_id":"49810560379194247739837403838602"}]
	String calledData = this.getRequest().getParameter("called_data");
	String[] called_dataStr = { "calledData", calledData, "600", "1", "str" };
	checkParamlist.add(called_dataStr);
	boolean isCalledDataNull = true;
	if (StringUtils.isNotBlank(calledData)) {
	    isCalledDataNull = false;
	} else {
	    calledData = "";
	}
	// app_key应用标识
	String app_key = this.getRequest().getParameter("app_key");
	String[] app_keyStr = { "app_key", app_key, "50", "0", "str" };
	checkParamlist.add(app_keyStr);
	// cust_account账号标识
	String cust_account = this.getRequest().getParameter("cust_account");
	String[] cust_accountStr = { "cust_account", cust_account, "50", "0", "str" };
	checkParamlist.add(cust_accountStr);
	// 发起语音短信的用户ID
	String ext_terminalCode = this.getRequest().getParameter("ext_terminalCode");
	String[] ext_terminalCodeStr = { "ext_terminalCode", ext_terminalCode, "50", "0", "str" };
	checkParamlist.add(ext_terminalCodeStr);
	// 时间戳
	String timestamp = this.getRequest().getParameter("timestamp");
	String[] timestampStr = { "timestamp", timestamp, "20", "0", "str" };
	checkParamlist.add(timestampStr);
	// 认证码
	String sign = this.getRequest().getParameter("sign");
	String[] signStr = { "sign", sign, "50", "0", "str" };
	checkParamlist.add(signStr);
	// 预约发起短信时间
	String schedule_send_time = this.getRequest().getParameter("schedule_send_time");
	String[] schedule_send_timeStr = { "schedule_send_time", schedule_send_time, "50", "1", "date" };
	checkParamlist.add(schedule_send_timeStr);
	// 重发的信息的原始id
	String voice_id = this.getRequest().getParameter("voice_id");
	String[] voice_idStr = { "voice_id", voice_id, "50", "1", "str" };
	checkParamlist.add(voice_idStr);
	// 语音通信预约后，通信发起sessionid接收地址
	String push_url = this.getRequest().getParameter("push_url");
	String[] push_urlStr = { "push_url", push_url, "1000", "1", "str" };
	checkParamlist.add(push_urlStr);
	if (StringUtils.isBlank(push_url)) {
	    push_url = "";
	}
	// 前导音
	String tts_content = this.getRequest().getParameter("tts_content");
	String[] tts_contentStr = { "tts_content", tts_content, "50", "1", "str" };
	checkParamlist.add(tts_contentStr);
	// 判断如果前导音为空未收到参数，则处理为-1，设置为-1，则使用原始语音通知
	if (StringUtils.isBlank(tts_content)) {
	    tts_content = "-1";
	}
	// ISV自行定义使用哪个号码发起通话
	String pool_ability_id = this.getRequest().getParameter("pool_ability_id");
	String[] pool_ability_idStr = { "pool_ability_id", pool_ability_id, "20", "1", "str" };
	checkParamlist.add(pool_ability_idStr);
	// 判断如果号码参数为空未收到参数，则处理为空字符串
	if (StringUtils.isBlank(pool_ability_id)) {
	    pool_ability_id = "";
	}
	// 是否为一批次
	String batch_number = this.getRequest().getParameter("batch_number");
	String[] batch_numberStr = { "batch_number", batch_number, "100", "1", "str" };
	checkParamlist.add(batch_numberStr);
	if (StringUtils.isBlank(batch_number)) {
	    batch_number = "";
	}
	// 强制使用平台号码(值为1时，强制使用平台号码发起)
	String usePlatNbr = this.getRequest().getParameter("usePlatNbr");
	String[] usePlatNbrStr = { "usePlatNbr", usePlatNbr, "20", "1", "str" };
	checkParamlist.add(usePlatNbrStr);
	if (StringUtils.isBlank(usePlatNbr) || !"1".equals(usePlatNbr)) { // 不为1时不强制使用平台号
	    usePlatNbr = "";
	}
	// 语音通知类型：VOICE70，70字文字语音通知；VOICE140，140字文字语音通知
	String voice_type = this.getRequest().getParameter("voice_type"); // 可以为空
	String[] voice_typeStr = { "voice_type", voice_type, "10", "1", "str" };
	checkParamlist.add(voice_typeStr);
	if (StringUtils.isBlank(voice_type)) {
	    voice_type = "";
	}
	JSONObject object = null;
	try {
	    object = this.checkParams(checkParamlist);
	    if (null == object) {
		object = new JSONObject();

		JSONArray calledJsonArray = new JSONArray();
		if (!isCalledDataNull) {
		    calledJsonArray = JSONArray.fromObject(calledData);
		    called = VoiceUtil.parsePhone(calledJsonArray);
		} else {
		    // 处理重复的电话号码
		    called = PhoneUtils.phoneNumDereplication(called);
		}
		// 被叫人数限定
		String[] calleeStr = called.split(",");
		if (calleeStr != null && calleeStr.length < calleeNum) {
		    // 查询应用信息
		    AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(app_key);
		    // 判断app信息是否为空
		    if (appExtendBean != null) {
			// 根据cust_account查询账号信息
			AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(cust_account);
			// 判断账号信息是否找到
			if (accountBean != null) {
			    // 验证秘钥信息
			    if (checkValidityService.toolsCheckSign(cust_account, accountBean.getKey_private(), timestamp, sign)) {
				// 获取语音短信能力类型标识
				String abilityType = AbilityTypeEnum.VOICE.getKey();
				abilityType = VoiceUtil.changeAbilityTypeByVoiceType(abilityType, voice_type, "audio", "运营平台");
				// 到运营平台验证账号相关信息--判断是否可以通话
				if (operationPlatformService.platformAuthentication(object, appExtendBean, accountBean, abilityType)) {
				    // 重新发起IMS文字语音信息
				    object = audeoNoticeService.sendAudeoNoticeLet(appExtendBean, accountBean, ext_terminalCode, voice_id, caller, called, schedule_send_time,
					    push_url, tts_content, pool_ability_id, batch_number, usePlatNbr, calledJsonArray, voice_type);
				} else {
				    object.put("result", "-1");
				    object.put("code", object.getString("code"));
				    object.put("describe", object.getString("describe"));
				}
			    } else {
				object.put("result", "-1");
				object.put("describe", "参数sign错误");
				object.put("code", "0001");
			    }
			} else {
			    object.put("result", "-1");
			    object.put("describe", "计费账号不存在");
			    object.put("code", "0002");
			}
		    } else {
			object.put("result", "-1");
			object.put("describe", "请使用正确的应用标识");
			object.put("code", "0007");
		    }
		} else {
		    object.put("result", "-1");
		    object.put("describe", "单次提交的手机号码数量不能超过" + calleeNum + "个");
		    object.put("code", "0502");
		}
	    }
	} catch (Exception e) {
	    log.info("********重新发起语音短信留言失败**********" + e);
	    object = new JSONObject();
	    object.put("result", "-1");
	    object.put("describe", "语音通知异常");
	    object.put("errorMsg", e.getMessage());
	    object.put("code", "0501");
	}

	// 计算结束时间
	double end = Calendar.getInstance().getTimeInMillis();
	// 计算发起接口道调用完毕所用的时间
	double during = Double.valueOf((end - begin)) / 1000;
	// 拼写写入日志内容
	String request_msg = "ext_terminalCode:" + ext_terminalCode + "|app_key:" + app_key + "|cust_account:" + cust_account + "|caller:" + caller + "|called:"
		+ (called.length() > 200 ? called.substring(0, 200) : called) + "|calledData:" + (calledData.length() > 200 ? calledData.substring(0, 200) : calledData)
		+ "|timestamp:" + timestamp + "|sign:" + sign + "|schedule_send_time:" + schedule_send_time + "|voice_id:" + voice_id + "|pool_ability_id:" + pool_ability_id
		+ "|usePlatNbr:" + usePlatNbr + "batch_number:" + batch_number + "|voice_type:" + voice_type + "|tts_content:" + tts_content + "|push_url:" + push_url;
	this.logService.logInterface(during, "sendAudeoNoticeLetV4", request_msg.length() > 500 ? request_msg.substring(0, 500) : request_msg,
		object.toString().length() > 200 ? object.toString().substring(0, 200) : object.toString(), object.getString("result").length() > 200 ? object.getString("result")
			.substring(0, 200) : object.getString("result"), DateUtils.getCurrentTime(), this.getRequest().getRemoteAddr(), caller);
	object.remove("errorMsg");
	return returnData(object.toString());
    }

    /**
     * 上传录音语音文件
     * 
     * @return
     */
    public String uploadAudeoFile() {
	log.info("load uploadAudeoFile 上传录音语音文件");
	long begin = Calendar.getInstance().getTimeInMillis();
	// 接口请求参数
	List<String[]> checkParamlist = new ArrayList<String[]>();
	// app_key应用标识
	String app_key = this.getRequest().getHeader("app_key");
	String[] app_keyStr = { "app_key", app_key, "50", "0", "str" };
	checkParamlist.add(app_keyStr);
	// cust_account账号标识
	String cust_account = this.getRequest().getHeader("cust_account");
	String[] cust_accountStr = { "cust_account", cust_account, "50", "0", "str" };
	checkParamlist.add(cust_accountStr);
	// 时间戳
	String timestamp = this.getRequest().getHeader("timestamp");
	String[] timestampStr = { "timestamp", timestamp, "20", "0", "str" };
	checkParamlist.add(timestampStr);
	// 认证码
	String sign = this.getRequest().getHeader("sign");
	String[] signStr = { "sign", sign, "50", "0", "str" };
	checkParamlist.add(signStr);
	JSONObject object = null;
	try {
	    object = this.checkParams(checkParamlist);
	    if (null == object) {
		object = new JSONObject();
		// 查询应用信息
		AppExtendBean appExtendBean = appExtendService.queryAppExtendByIdentify(app_key);
		// 判断app信息是否为空
		if (appExtendBean != null) {
		    // 根据cust_account查询账号信息
		    AccountBean accountBean = accountExtendService.queryAccountDetailByCustAccount(cust_account);
		    // 判断账号信息是否找到
		    if (accountBean != null) {
			// 验证秘钥信息
			if (checkValidityService.toolsCheckSign(cust_account, accountBean.getKey_private(), timestamp, sign)) {
			    // 首先开始文件上传
			    SimpleDateFormat sdfMonth = new SimpleDateFormat("yyyyMM");
			    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			    String fileName = null;
			    // 拼写目录名称
			    String monthStr = sdfMonth.format(new Date()) + "/";
			    fileName = sdf.format(new Date()) + ((int) (Math.random() * 9000) + 1000);// 上传,调接口的名字
			    // 获取项目绝对路径
			    String dpath = this.getRequest().getSession().getServletContext().getRealPath("../");
			    log.info("文件存储目录：" + dpath);
			    // 将各个账号的录音信息存放在相应账号的目录下
			    dpath = dpath + "/upload_voice/" + cust_account + "/" + monthStr;
			    // 创建文件夹
			    File fdir = new File(dpath);
			    if (!fdir.exists()) {
				fdir.mkdirs();
			    }
			    // 读取数据流
			    byte[] data = null;
			    try {
				data = HttpRequest.readStream(this.getRequest().getInputStream());

			    } catch (SocketTimeoutException e1) {
				e1.printStackTrace();
			    } catch (IOException e1) {
				e1.printStackTrace();
			    }
			    // 查看文件大小
			    Long fileLength = (long) data.length;
			    // log.info("----------------------------------"+fileLength);
			    // 判断上传文件大小，如果文件大于配置的文件大小，则报错
			    if (fileMaxLength < fileLength) {
				object.put("result", "-1");
				object.put("describe", "文件大小超过10M");
				object.put("code", "0506");
			    } else {
				// 根据系统时间生成上传后保存的文件名
				String t_ext = ".mp3";
				// 拼写目录信息
				String completeFileName = dpath + fileName + t_ext;
				File localFileName = new File(completeFileName);
				try {
				    // 写入文件
				    FileOutputStream fileOutputStream = new FileOutputStream(localFileName);
				    fileOutputStream.write(data);
				    fileOutputStream.close();
				} catch (FileNotFoundException e1) {
				    e1.printStackTrace();
				    object.put("result", "-1");
				    object.put("describe", "文件获取失败");
				    object.put("code", "0505");
				} catch (Exception e) {
				    e.printStackTrace();
				    object.put("result", "-1");
				    object.put("describe", "文件获取失败");
				    object.put("code", "0505");
				}
				if (StringUtils.isBlank(object.optString("result"))) {
				    // 开始处理上传文件到IMS
				    Map<String, String> paramMap = new HashMap<String, String>();
				    paramMap.put("Name", fileName);
				    try {
					object = audeoNoticeService.uploadFile(app_key, cust_account, completeFileName, fileName + t_ext,"","");
				    } catch (Exception e) {
					e.printStackTrace();
				    }
				}

			    }

			} else {
			    object.put("result", "-1");
			    object.put("describe", "参数sign错误");
			    object.put("code", "0001");
			}
		    } else {
			object.put("result", "-1");
			object.put("describe", "计费账号不存在");
			object.put("code", "0002");
		    }
		} else {
		    object.put("result", "-1");
		    object.put("describe", "请使用正确的应用标识");
		    object.put("code", "0007");
		}
	    }
	} catch (Exception e) {
	    log.info("********上传录音语音短信**********" + e);
	    object = new JSONObject();
	    object.put("result", "-1");
	    object.put("describe", "语音通知异常");
	    object.put("errorMsg", e.getMessage());
	    object.put("code", "0501");
	}
	// 计算结束时间
	double end = Calendar.getInstance().getTimeInMillis();
	// 计算发起接口道调用完毕所用的时间
	double during = Double.valueOf((end - begin)) / 1000;
	// 拼写写入日志内容
	String request_msg = "app_key:" + app_key + "|cust_account:" + cust_account + "|timestamp:" + timestamp + "|sign:" + sign;
	this.logService.logInterface(during, "uploadFileV4", request_msg, object.toString(), object.getString("result"), DateUtils.getCurrentTime(), this.getRequest()
		.getRemoteAddr(), "");
	object.remove("errorMsg");
	return returnData(object.toString());
    }
}
